#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define LEFT "["
#define RIGHT "]"
#define LABLE "#"
#define LINE_SIZE 1024
#define ARGV_SIZE 32
#define DELIM " \r"
#define EXIT_CODE 44


int lastcode = 0;
int quit = 0;
char commandline[LINE_SIZE];
char *argv[ARGV_SIZE];
char pwd[LINE_SIZE];

char myenv[LINE_SIZE];

const char* getusername()
{
    return getenv("USER");
}

const char* gethostname()
{
    return getenv("HOSTNAME");
}

void getpwd()
{
    getcwd(pwd,sizeof(pwd));
}

void Interact(char* cline,int size)
{
    getpwd();
    printf(LEFT"%s@%s %s"RIGHT""LABLE,getusername(),gethostname(),pwd);
    char* s = fgets(cline,size,stdin);
    assert(s);
    (void)s;
    //abcd\n\0
    cline[strlen(cline)-1]='\0';
}

int splitstring(char cline[],char* _argv[])
{

    int i = 0;
    argv[i++]=strtok(cline,DELIM);
    while(_argv[i++] = strtok(NULL,DELIM));
    return  i-1;

}

void NormalExcute(char* _argv[])
{
    pid_t id = fork();
    if(id<0)
    {
        perror("fork");
        return;
    }
    else if(id==0)
    {
        //子进程
        execvp(_argv[0],_argv);
        exit(EXIT_CODE);
    }
    else
    {
        int status = 0;
        pid_t ret = waitpid(id,&status,0);
        if(ret==id)
        {
            lastcode = WIFEXITED(status);
        }
    }

}
int InterCommand(char* _argv[],int _argc)
{
    if(_argc==2 && strcmp(_argv[0],"cd")==0)
    {
        chdir(_argv[1]);
        getpwd();//更新pwd的目录，能刷新到命令行
        //更新环境变量
        sprintf(getenv("PWD"),"%s",pwd);
        return 1;
    }
    else if(_argc==2 && strcmp(_argv[0],"echo")==0)
    {
        if(strcmp(_argv[1],"$?")==0)
        {
            printf("%d\n",lastcode);
            lastcode = 0;
        }
        else if(*_argv[1]=='$')
        {
            printf("%s\n",getenv(_argv[1]+1));
        }
        else
        {
            printf("%s",_argv[1]);
        }
        return 1;
    }
    else if(_argc==2 && strcmp(_argv[0],"export")==0)
    {
        strcpy(myenv,_argv[1]);
        putenv(myenv);
        return 1;
    }

    if(strcmp(_argv[0],"ls")==0)
    {
        _argv[_argc++] = "--color";
        _argv[_argc] = NULL;
    }
    return 0;
}



int main()
{
    while(!quit)
    {
        //1
        
        //2交互问题，获取命令行--> ls -a -l
        Interact(commandline,sizeof(commandline)); 
        
        //3字串分割问题，解析命令
        int argc = splitstring(commandline,argv); 
        if(argc==0) continue;
        //test
        // for(i = 0;argv[i];i++)
        // {
        //     printf("[%d]:%s\n",i,argv[i]);
        // }
        
        //4指令的判断,要判断是否是内建命令
        int n = InterCommand(argv,argc);
        
        //5普通命令的执行
        if (!n) NormalExcute(argv); 
    }

    return 0;
}


